package com.mercadopago.sonda;

import java.io.IOException;
import java.io.InputStreamReader;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.mercadopago.MercadoPago;
import com.mercadopago.ParseXmlProcessStatus;
import com.mercadopago.exceptions.MercadoPagoParseXmlException;
import com.mercadopago.types.Result;
import com.mercadopago.types.Status;

public final class MercadoPagoSonda {
	
	private Log logger = LogFactory.getLog(getClass());

	/**
	 * seller_op_id
	 */
	private String codigoReferenciaOperacao;

	/**
	 * mp_op_id
	 */
	private String identificadorOperacaoMercadoPago;

	/**
	 * acc_id
	 */
	private Long numeroContaVendedor;

	/**
	 * status
	 */
	private Status statusPagamento;

	/**
	 * token
	 */
	private String token;

	/**
	 * seller_op_id
	 * @param java.lang.String
	 */
	public void setCodigoReferenciaOperacao(String codigoReferenciaOperacao) {
		this.codigoReferenciaOperacao = codigoReferenciaOperacao;
	}

	/**
	 * mp_op_id
	 * @param java.lang.String
	 */
	public void setIdentificadorOperacaoMercadoPago(
			String identificadorOperacaoMercadoPago) {
		this.identificadorOperacaoMercadoPago = identificadorOperacaoMercadoPago;
	}

	/**
	 * acc_id
	 * @param java.lang.Long
	 */
	public void setNumeroContaVendedor(Long numeroContaVendedor) {
		this.numeroContaVendedor = numeroContaVendedor;
	}

	/**
	 * status
	 * @param com.mercadopago.types.StatusPagamento
	 */
	public void setStatusPagamento(Status statusPagamento) {
		this.statusPagamento = statusPagamento;
	}

	/**
	 * token
	 * @param java.lang.String
	 */
	public void setToken(String token) {
		this.token = token;
	}

	/**
	 * Valida parametros
	 * @throws MercadoPagoSondaException
	 */
	private void validateParameters() throws MercadoPagoSondaException {
		logger.debug("Validando dados sonda mercado pago");
		
		logger.debug("Validando codigoReferenciaOperacao");
		if (codigoReferenciaOperacao == null
				|| codigoReferenciaOperacao.equals(""))
			throw new MercadoPagoSondaException(
					"O código de referencia é inválido.");

		logger.debug("Validando identificadorOperacaoMercadoPago");
		if (identificadorOperacaoMercadoPago == null
				|| identificadorOperacaoMercadoPago.equals(""))
			throw new MercadoPagoSondaException(
					"O identificador da operação do mercado pago é inválido.");

		logger.debug("Validando numeroContaVendedor");
		if (numeroContaVendedor == null || numeroContaVendedor.equals(""))
			throw new MercadoPagoSondaException(
					"O número da conta do vendedor é inválido.");

		logger.debug("Validando token");
		if (token == null || token.equals(""))
			throw new MercadoPagoSondaException("O token é inválido.");
	}

	/**
	 * Envia verificação de status
	 * @return com.mercadopago.types.Result
	 * @throws MercadoPagoSondaException
	 */
	public Result runSonda() throws MercadoPagoSondaException {
		validateParameters();

		logger.debug("Montando método post");
		PostMethod postMethod = new PostMethod(MercadoPago.URL_SUBMIT_SONDA);

		logger.debug("configurando parametros");
		postMethod.addParameter("mp_op_id", identificadorOperacaoMercadoPago);
		postMethod.addParameter("seller_op_id", codigoReferenciaOperacao);
		postMethod.addParameter("acc_id", String.valueOf(numeroContaVendedor));
		postMethod.addParameter("sonda_key", token);
		if (statusPagamento != null)
			postMethod.addParameter("status", statusPagamento.value());

		try {
			logger.debug("criando HttpClient");
			HttpClient httpClient = new HttpClient();
			
			logger.debug("executando envio da sonda");
			int statusResponse = httpClient.executeMethod(postMethod);

			logger.debug("verificando status de retorno");
			if (statusResponse != HttpStatus.SC_OK) {
				throw new MercadoPagoSondaException(
						"Erro durante comunicação com a sonda do mercado pago.");
			} else {
				logger.debug("status de retorno OK, processando resposta");
				InputStreamReader inputStreamReader = new InputStreamReader(
						postMethod.getResponseBodyAsStream(),
						postMethod.getRequestCharSet());
				
				logger.debug("fazendo parse da resposta da sonda");
				ParseXmlProcessStatus parseXmlProcessStatus = new ParseXmlProcessStatus();
				return (Result) parseXmlProcessStatus.parseResult(inputStreamReader);
			}
		} catch (HttpException e) {
			throw new MercadoPagoSondaException(e);
		} catch (IOException e) {
			throw new MercadoPagoSondaException(e);
		} catch (MercadoPagoParseXmlException e) {
			throw new MercadoPagoSondaException(e);
		} finally {
			logger.debug("liberando conexão da sonda");
			postMethod.releaseConnection();
		}
	}

}
